function [cpstatus,cpmsg] = cpfile(fromfile,tofile,force)
% cpfile  - copies a file
%
% FORMAT:       [cpstatus,cpmsg] = cpfile(fromfile, tofile [,force])
%
% Input Fields:
%
%       fromfile    name of the file to use as source file
%       tofile      name of the target file
%       force       if given and set to 1, 'force', or 'overwrite'
%                   copying will be forced
%
% if requested, returns a PERL-like status (0 for unsuccessful!) and
% a message indicating what went wrong (or empty if successful)

% Version:  v0.7f
% Build:    8110521
% Date:     Nov-05 2008, 9:00 PM CET
% Author:   Jochen Weber, SCAN Unit, Columbia University, NYC, NY, USA
% URL/Info: http://wiki.brainvoyager.com/BVQXtools

% settings
icpbuffer = 65536;
cpstatus  = 0;
cpmsg     = '';

% enough arguments ?
if nargin < 2
    error( ...
        'BVQXtools:TooFewArguments',...
        'Too few arguments. Try ''help %s''.',...
        mfilename ...
    );
end

if ~ischar(fromfile) || ...
   ~ischar(tofile) || ...
    isempty(fromfile) || ...
    isempty(tofile)
    error( ...
        'BVQXtools:BadArgument',...
        'Bad argument.' ...
    );
end

% options
if nargin < 3 || ...
    isempty(force)
    force = 0;
elseif isnumeric(force) && ...
   ~isnan(force(1)) && ...
    force(1) ~= 0
    force = 1;
elseif ischar(force) && ...
    any('fo' == lower(force(1)))
    force = 1;
else
    force = 0;
end

% filename mangling check
if ispc
    fromfile = strrep(fromfile(:)', '/', filesep);
    tofile = strrep(tofile(:)', '/', filesep);
else
    fromfile = strrep(fromfile(:)', '\', filesep);
    tofile = strrep(tofile(:)', '\', filesep);
end

try

    % check for target being a folder
    if exist(tofile,'dir') == 7
        [topartfn{1:3}] = fileparts(fromfile);
        if ~strcmp(filesep, tofile((end+1-length(filesep)):end))
            tofile = [tofile filesep];
        end
        tofile = [tofile topartfn{2} topartfn{3}];
    end

    % check for existing target file
    if exist(tofile, 'file') == 2 && ...
        force < 1
        error( ...
            'BVQXtools:NoForceRequested',...
            'Tofile ''%s'' already exists; not overwritten.',...
            tofile ...
        );
    end

    % open source file and check for handle
    sfp = fopen(fromfile, 'r');
    if sfp < 1
        error( ...
            'BVQXtools:FileNotReadable',...
            'Couldn''t read from file: %s',...
            fromfile ...
        );
    end

    % open destination file and check for handle
    tfp = fopen(tofile, 'w');
    if tfp < 1
        fclose(sfp);
        error( ...
            'BVQXtools:FileNotWritable',...
            'Couldn''t write to file: %s',...
            tofile ...
        );
    end

    % rewind source file, write content to target and close file handles
    frewind(sfp);
    while ~feof(sfp)
        buff = fread(sfp, icpbuffer, '*uint8');
        fwrite(tfp, buff, 'uint8');
        if numel(buff) < icpbuffer
            break;
        end
    end
    fclose(sfp);
    fclose(tfp);

    cpstatus = 1;

catch
    cpmsg = lasterr;
end
